//301 重定向、短链重定向、pc端页面在移动端打开切换至移动站页面
const config = require('../config/env')
const menu = require('../config/menu')

function userAgent(ua) {
  var isWindowsPhone = /(?:Windows Phone)/.test(ua),
    isSymbian = /(?:SymbianOS)/.test(ua) || isWindowsPhone,
    isAndroid = /(?:Android)/.test(ua),
    isFireFox = /(?:Firefox)/.test(ua),
    isChrome = /(?:Chrome|CriOS)/.test(ua),
    isTablet =
      /(?:iPad|PlayBook)/.test(ua) || (isAndroid && !/(?:Mobile)/.test(ua)) || (isFireFox && /(?:Tablet)/.test(ua)), //判断平板
    isPhone = /(?:iPhone)/.test(ua) && !isTablet,
    isPc = !isPhone && !isAndroid && !isSymbian && !isTablet
  return {
    isTablet: isTablet,
    isPhone: isPhone,
    isAndroid: isAndroid,
    isPc: isPc
  }
}

module.exports = (req, res, next) => {
  // let path = req.originalUrl
  // var fileReg = /\.jpg|\.png|\.gif|\.ico|\?v|\?t|\.js|.css/i
  // if(fileReg.test(path)) return
  let ua = req.headers['user-agent']
  let host = req.headers.host
  // 如果当前域名为https://www.zlketang.com.cn/并且不是注会sem落地页强制跳转注会sem落地页面
  let path = req.originalUrl
  let url = req.url
  // 过滤css,js等文件请求
  var fileReg = /\.jpg|\.png|\.gif|\.ico|\?v|\?t|\.js|.css/i
  if (fileReg.test(path)) return next()

  if (
      host.includes('sem360.zlketang.com') 
      && req.path !== '/sem_360_page' 
      && req.path !== '/sem_360_lading' 
      && req.path !== '/sem_360_lading_new'
      && req.path !== '/sem_360_lading_new2'
      ) {
    res.redirect(301, '/sem_360_page')
    return
  }

  if (req.headers.host.includes('zlketang.com.cn') && userAgent(ua).isPc && !path.includes('/sem/cpa')) {
    let isValidUrls = /^\/sem_teach_pc\/cpa\/$/.test(path) || /^\/sem\/cpa\/$/.test(path)
    if (!isValidUrls) {
      res.redirect(301, '/sem/cpa')
      return
    }
  }

  // /sem_mobile/cpa  /sem_teach_mobile/cpa
  if (host.includes('zlketang.com.cn') && !userAgent(ua).isPc) {
    let isValidUrls =
      /^\/sem_mobile\/cpa\/$/.test(path) ||
      /^\/sem_teach_mobile\/cpa\/?$/.test(path) ||
      /^\/sem_mobile\/cpa\/?[?].+/.test(path) ||
      /^\/sem_teach_mobile\/cpa\/?[?].+/.test(path) ||
      /^\/new_sem_mobile\/cpa\/?[?].+/.test(path) ||
      /^\/new_sem_mobile\/service\/?[?].+/.test(path) ||
      /^\/sem_zj_mobile\/?/.test(path)
    if (!isValidUrls) {
      let queryArr = url.split('?')
      let queryStr = ''
      if (queryArr[1]) {
        queryStr = '?' + queryArr[1]
      }
      let redirectUrl = queryStr ? '/sem_mobile/cpa/' + queryStr : '/sem_mobile/cpa/'
      res.redirect(301, redirectUrl)
      return
    }
  }
  if (host.includes('zlketang.com.cn')) {
    return next()
  }
  /*
    短链拦截方案，格式为：http[s]://*.zlketang.*[/]?a=XXXX 的将被node服务器拦截，重定向到指定页面。
    其中：
    （1）http[s]://*.zlketang.*[/]?a=XXXX 会被重定向到 http[s]://*.zlketang.*[/]ac/zl_redirect?t=XXXX（普通打标链接）
    （2）http[s]://*.zlketang.*[/]?b=XXXX&zlcode= 会被重定向到 http[s]://*.zlketang.*[/]ac/drainage_redirect?t=XXXX&zlcode=
  */

  if (host.includes('zlketang') && path.split('?')[0] === '/' && (req.query.a || req.query.b)) {
    var a = req.query.a // 普通打标链接标识
    var b = req.query.b // 带激活码打标链接标识
    var zlcode = req.query.zlcode || '' // 打标链接中的激活码
    if (a) {
      res.redirect(301, '/ac/zl_redirect?t=' + a)
    } else if (b) {
      res.redirect(301, '/ac/drainage_redirect?t=' + b + '&zlcode=' + zlcode)
    }
    return
  }
  // 未知异常状态，默认使用 500
  let os = userAgent(ua)
  let id
  // 处理题库页面为伪静态
  let newREG = /\/exercises\/\d+\.html/
  if (newREG.test(path)) {
    id = path.match(/\d+/g)[0]
    path = '/exercises/index.html?profession_id=' + id
    url = '/exercises/index.html?profession_id=' + id
  }
  // 重定 向需要去掉字段的链接
  function handleUrl(path_name) {
    // 向所有带链接带mobile的去掉mobile
    let mobileRedirectReg = /\/mobile($|\/.*)/
    if (mobileRedirectReg.test(path_name) && path_name.startsWith('/mobile')) {
      path_name = path_name.replace(/\/mobile($|\/)/, '/')
    }

    // 重定向所有带链接带news的去掉news
    // 以/news开头
    let reg = /\/(news$|news\/)/
    if (reg.test(path_name)) {
      path_name = path_name.replace('/news', '')
    }

    // 重定向商城链接
    if (path_name.indexOf('/courses/?profession_id') > -1) {
      id = req.query.profession_id
      path_name = path_name.split('?')[0] + id + '.html'
    }
    // 对资讯老链接处理，https://www.zlketang.com/news/cjkj/stuff/detail?id=470 这样的链接处理成https://www.zlketang.com/news/cjkj/stuff_detail/470.html
    // 链接同时带上 专业字段 如cjkj、zjkj 和 资讯类型字段如dynamic、guide 同时 链接带上 detail?id=470 这样的标识，应该就是老的咨询链接
    let { professionMap, submenuMap, training, kjsc } = menu
    //资讯类型，专业数组
    let navArr = [],
      professionArr = []
    Object.values(submenuMap).forEach(navItem => navArr.push(navItem.en))
    Object.values(training).forEach(navItem => navArr.push(navItem.en))
    Object.values(kjsc).forEach(navItem => navArr.push(navItem.en))
    Object.values(professionMap).forEach(proItem => professionArr.push(proItem.en))
    let isHasNav = navArr.some(navItem => path_name.includes(navItem))
    let isHasPro = professionArr.some(proItem => path_name.includes(proItem))
    if (isHasNav && isHasPro && /\/detail\?id=\d+$/gi.test(path_name)) {
      path_name =
        path_name.slice(0, path_name.lastIndexOf('/')) +
        '_' +
        path_name.slice(path_name.lastIndexOf('/') + 1).replace('?id=', '/') +
        '.html'
    }
    return path_name
  }

  // 判断当前客户端与使用域名是否匹配
  function redirectDomain() {
    // PC域名列表
    let pcDomainArr = ['www.zlketang.com', 'cp.zlketang.com', 'shenji.zlketang.com', 'localhost:3002']
    // 移动端域名列表
    let mbDomainArr = ['wap.zlketang.com', 'cpm.zlketang.com', 'shenjim.zlketang.com', 'localhost:3004']
    // 强制https的域名
    let hostArr = ['www.zlketang.com', 'cp.zlketang.com', 'shenji.zlketang.com']
    // 判断为本地环境 isLocal
    let isLocal = config.environment.includes('isLocal')
    // 重定向时的协议字符串 protocol
    let protocol = 'https://'
    if (isLocal) {
      protocol = req.protocol + '://'
    }

    // 服务端获取 x-forwarded-proto，以确定http协议 [xForwardedProto]
    let xForwardedProto = req.headers['x-forwarded-proto']
    xForwardedProto = (xForwardedProto && xForwardedProto.toLowerCase()) || ''
    // 是否为PC端的请求 isPcRequest
    let isPcRequest = pcDomainArr.some(item => host && host.includes(item))
    // 是否为强制https的域名 isWhiteHost
    let isWhiteHost = hostArr.some(item => host && host.includes(item))

    // 【1】链接中，以“/mobile”或“/news”开头的链接，去掉“news和mobile”【HuBin】-begin
    if (path.startsWith('/mobile/') || path.startsWith('/news/')) {
      path = handleUrl(path)
      res
        .location(protocol + host + path)
        .status(301)
        .end()
      return
    }
    // 【1】链接中，以“/mobile”或“/news”开头的链接，去掉“news和mobile”【HuBin】-end

    /* ======不进行重定向跳转====== */

    // ac-活动页面 fileapp- app协议页面 /zlapp -通过路径打开app【HuBin】
    let noRedirectPaths = ['/ac/', '/fileapp/', '/zlapp/', '/study_plan_ac.html']
    if (noRedirectPaths.some(item => path.includes(item))) return next()

    /* ======不进行重定向跳转====== */

    // 【2】PC端域名在移动端打开，重定向到移动端页面 - begin
    // 获取移动端域名
    function _getMobileHost() {
      if (os.isPc || !isPcRequest) return false
      let findIndex = pcDomainArr.findIndex(item => {
        return host.includes(item)
      })
      // 查找到需要跳转的移动端域名：currentHost
      let currentHost = findIndex > -1 ? mbDomainArr[findIndex] : ''
      return currentHost
    }
    // 当前需要跳转的移动端域名
    let currentMobileHost = _getMobileHost()
    if (currentMobileHost) {
      // 获取处理后的路径path
      path = handleUrl(path)
      // 重定向301
      res
        .location(protocol + currentMobileHost + path)
        .status(301)
        .end()
      return
    }
    // 【2】PC端域名在移动端打开，重定向到移动端页面 - end

    // 【3】非本地环境且在名单内，都需要强制重定向到https逻辑
    if (isWhiteHost && (!xForwardedProto || xForwardedProto === 'http')) {
      path = handleUrl(path)
      res
        .location(protocol + host + path)
        .status(301)
        .end()
      return
    }
    // 【4】以上均未满足条件，直接到下一个中间件
    return next()
  }
  redirectDomain()
}
